import cv2 as cv
import numpy as np

def reorder(myPoints):
    myPoints = myPoints.reshape((4, 2))
    myPointsNew = np.zeros((4, 1, 2), dtype=np.int32)
    add = myPoints.sum(1)

    myPointsNew[0] = myPoints[np.argmin(add)]
    myPointsNew[3] = myPoints[np.argmax(add)]
    diff = np.diff(myPoints, axis=1)
    myPointsNew[1] = myPoints[np.argmin(diff)]
    myPointsNew[2] = myPoints[np.argmax(diff)]

    return myPointsNew


def getBiggestContour(contours):
    biggest = np.array([])
    max_area = 0
    for contour in contours:
        area = cv.contourArea(contour)
        if area > 5000:
            peri = cv.arcLength(contour, True)
            approx = cv.approxPolyDP(contour, 0.1 * peri, True)
            if area > max_area and len(approx) == 4:
                biggest = approx
                max_area = area
    return biggest, max_area


def drawRectangle(img, biggest, thickness):
    cv.line(img, (biggest[0][0][0], biggest[0][0][1]), (biggest[1][0][0], biggest[1][0][1]), (0, 255, 0), thickness)
    cv.line(img, (biggest[0][0][0], biggest[0][0][1]), (biggest[2][0][0], biggest[2][0][1]), (0, 255, 0), thickness)
    cv.line(img, (biggest[3][0][0], biggest[3][0][1]), (biggest[2][0][0], biggest[2][0][1]), (0, 255, 0), thickness)
    cv.line(img, (biggest[3][0][0], biggest[3][0][1]), (biggest[1][0][0], biggest[1][0][1]), (0, 255, 0), thickness)
    return img



img = cv.imread("assets/book.jpg")
grayImg = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv.imshow("originalWin", img)
cv.imshow('imgWin', grayImg)

ret, threshImg = cv.threshold(grayImg, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
cv.imshow('imgWin', threshImg)
contours, hier = cv.findContours(threshImg, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
biggest, area = getBiggestContour(contours)
biggest = reorder(biggest)
drawRectangle(img, biggest, 2)

pts1 = np.float32(biggest)
pts2 = np.float32([[0, 0], [300, 0], [0, 400], [300, 400]])
matrix = cv.getPerspectiveTransform(pts1, pts2)
imgWarpColored = cv.warpPerspective(img, matrix, (300, 400))

cv.imshow("originalWin", img)
cv.imshow("finalWin", imgWarpColored)

cv.waitKey(0)